1 module hip.hiprenderer.backend.d3d.defaultshaders;
2 import hip.api.renderer.core;
3 import hip.config.renderer;
4 
5 private enum D3DDefaultShadersPath = __MODULE__;
6 
7 static if(!HasDirect3D)
8     immutable DefaultShader[] DefaultShaders;
9 else:
10 
11 immutable DefaultShader[] DefaultShaders = [
12     HipShaderPresets.DEFAULT: DefaultShader(D3DDefaultShadersPath, &getDefaultVertex, &getDefaultVertex),
13     HipShaderPresets.FRAME_BUFFER: DefaultShader(D3DDefaultShadersPath, &getFrameBufferVertex, &getFrameBufferFragment),
14     HipShaderPresets.GEOMETRY_BATCH: DefaultShader(D3DDefaultShadersPath, &getGeometryBatchVertex, &getGeometryBatchFragment),
15     HipShaderPresets.SPRITE_BATCH: DefaultShader(D3DDefaultShadersPath, &getSpriteBatchVertex, &getSpriteBatchFragment),
16     HipShaderPresets.BITMAP_TEXT: DefaultShader(D3DDefaultShadersPath, &getBitmapTextVertex, &getBitmapTextFragment),
17     HipShaderPresets.NONE: DefaultShader(D3DDefaultShadersPath)
18 ];
19 
20 private {
21 
22     string getDefaultFragment()
23     {
24         return q{
25         float4 main() : SV_TARGET
26         {
27             return float4(1.0f, 1.0f, 1.0f, 1.0f);
28         }};
29     }
30     string getFrameBufferFragment()
31     {
32         return q{
33             Texture2D uTex1;
34             SamplerState state;
35 
36             float4 main(float2 inTexST : inTexST) : SV_TARGET
37             {
38                 return uTex1.Sample(state, inTexST);
39             }
40         };
41     }
42     string getGeometryBatchFragment()
43     {
44         return q{
45 
46             cbuffer FragVars
47             {
48                 float4 uGlobalColor : uGlobalColor;
49             };
50 
51             float4 main(float4 inVertexColor : inVertexColor) : SV_TARGET
52             {
53                 return inVertexColor * uGlobalColor;
54             }
55         };
56     }
57     /**
58     *   Creates a massive switch case for supporting array of textures.
59     *   D3D11 causes an error if trying to access texture with a variable
60     *   instead of a literal.
61     */
62     string getSpriteBatchFragment()
63     {
64         import hip.util.conv:to;
65         import hip.hiprenderer.renderer;
66         int sup = HipRenderer.getMaxSupportedShaderTextures();
67         string textureSlotSwitchCase = "\tswitch(tid)\n\t{\n"; //Switch textureID
68         for(int i = 1; i < sup; i++)
69         {
70             textureSlotSwitchCase~= "\t\tcase "~ to!string(i)~": "~
71             "return uTex["~to!string(i)~"].Sample(state["~to!string(i)~"], texST) * inVertexColor * uBatchColor;\n";
72         }
73         textureSlotSwitchCase~= "\t\tdefault: return uTex[0].Sample(state[0], texST) * inVertexColor * uBatchColor;";
74         textureSlotSwitchCase~= "\n\t}";
75 
76         return "Texture2D uTex["~to!string(sup)~"];
77     SamplerState state["~to!string(sup)~"];"~q{
78     cbuffer input
79     {
80         float4 uBatchColor: uBatchColor;
81     };
82 
83     float4 main(float4 inVertexColor : inColor, float2 texST : inTexST, float inTexID : inTexID) : SV_TARGET
84     }~"{"~
85     q{
86             // return uBatchColor * uTex.Sample(state, inTexST);
87             int tid = int(inTexID);
88 
89             //switch(tid)...
90             //case 1:
91                 //return uTex[1].Sample(state[1], texST) * inVertexColor * uBatchColor;
92     } ~ textureSlotSwitchCase ~ "\n}";
93     }
94 
95     string getBitmapTextFragment()
96     {
97         return q{
98 
99             cbuffer FragVars
100             {
101                 float4 uColor : uColor;
102             };
103 
104             Texture2D uSampler1;
105             SamplerState state;
106 
107             float4 main(float2 inTexST : inTexST) : SV_TARGET
108             {
109                 //The texture is read as monochromatic
110                 float r = uSampler1.Sample(state, inTexST)[0];
111 
112                 return float4(r,r,r,r) * uColor;
113             }
114         };
115     }
116 
117     string getDefaultVertex()
118     {
119         return q{
120         float4 main(float2 pos : Position) : SV_POSITION
121         {
122             return float4(pos.x, pos.y, 0.0f, 1.0f);
123         }};
124     }
125     string getFrameBufferVertex()
126     {
127         return q{
128             struct VSOut
129             {
130                 float2 inTexST : inTexST;
131                 float4 outPosition : SV_POSITION;
132             };
133 
134             VSOut main(float2 pos : vPosition, float2 vTexST : vTexST)
135             {
136                 VSOut ret;
137                 ret.outPosition = float4(pos.x, pos.y, 0.0, 1.0);
138                 ret.inTexST = vTexST;
139                 return ret;
140             }
141         };
142     }
143     string getGeometryBatchVertex()
144     {
145         return q{
146 
147             cbuffer Geom
148             {
149                 float4x4 uMVP: uMVP;
150             };
151             struct VSOut
152             {
153                 float4 inVertexColor : inVertexColor;
154                 float4 outPosition : SV_POSITION;
155             };
156 
157             VSOut main(float3 vPosition: vPosition, float4 vColor: vColor)
158             {
159                 VSOut ret;
160                 ret.outPosition = mul(float4(vPosition, 1.0), uMVP);
161                 ret.inVertexColor = vColor;
162                 return ret;
163             }
164         };
165     }
166     string getSpriteBatchVertex()
167     {
168         return q{
169             struct VSOut
170             {
171                 float4 inColor : inColor;
172                 float2 inTexST : inTexST;
173                 float  inTexID : inTexID;
174                 float4 vPosition: SV_POSITION;
175             };
176 
177             cbuffer Cbuf
178             {
179                 float4x4 uMVP: uMVP;
180             };
181 
182             VSOut main(
183                 float3 pos   : vPosition,
184                 float4 col   : vColor,
185                 float2 texST : vTexST,
186                 float  texID : vTexID
187                 )
188             {
189                 VSOut output;
190                 float4 position = float4(pos.x, pos.y, pos.z, 1.0f);
191                 output.vPosition = mul(position, uMVP);
192 
193                 output.inTexST = texST;
194                 output.inColor = col;
195                 output.inTexID = texID;
196                 return output;
197             }
198         };
199     }
200     string getBitmapTextVertex()
201     {
202         return q{
203 
204             cbuffer Cbuf
205             {
206                 float4x4 uMVP;
207             };
208 
209             struct VSOut
210             {
211                 float2 inTexST : inTexST;
212                 float4 outPosition : SV_POSITION;
213             };
214 
215             VSOut main(float2 vPosition : vPosition, float2 vTexST : vTexST)
216             {
217                 VSOut ret;
218                 ret.outPosition = mul(float4(vPosition, 1.0, 1.0), uMVP);
219                 ret.inTexST = vTexST;
220                 return ret;
221             }
222         };
223     }
224 }